package com.xmut.mall.product.service.impl;

import cn.hutool.Hutool;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import com.xmut.mall.product.entity.SkuInfoEntity;
import com.xmut.mall.product.entity.SpuInfoEntity;
import com.xmut.mall.product.feign.CouponFeignService;
import com.xmut.mall.product.feign.MemberFeignService;
import com.xmut.mall.product.feign.OrderFeignService;
import com.xmut.mall.product.feign.WareFeignService;
import com.xmut.mall.product.myenum.*;
import com.xmut.mall.product.service.SkuInfoService;
import com.xmut.mall.product.service.SpuInfoService;
import com.xmut.mall.product.service.TradeService;
import com.xmut.mall.product.to.CreateOrderDto;
import com.xmut.mall.product.utils.RespBean;
import com.xmut.mall.product.vo.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.client.exception.MQBrokerException;
import org.apache.rocketmq.client.exception.MQClientException;
import org.apache.rocketmq.client.producer.DefaultMQProducer;
import org.apache.rocketmq.client.producer.SendResult;
import org.apache.rocketmq.common.message.Message;
import org.apache.rocketmq.remoting.exception.RemotingException;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service("tradeService")
public class TradeServiceImpl implements TradeService {

    @Autowired
    private SkuInfoService skuInfoService;

    @Autowired
    private WareFeignService wareFeignService;

    @Autowired
    private MemberFeignService memberFeignService;

    @Autowired
    private CouponFeignService couponFeignService;

    @Autowired
    private SpuInfoService spuInfoService;

    @Autowired
    private OrderFeignService orderFeignService;


    /**
     * 根据map参数创建交易订单
     *
     * @param params
     * @return
     */
    @Transactional(rollbackFor = Exception.class)
    @Override
    public RespBean createTrade(Map<String, Object> params) {
        String type = MapUtil.getStr(params, "type");
        Long userId = MapUtil.getLong(params, "userId");
        String userName = MapUtil.getStr(params, "userName");
        List<Long> useChooseCouponIDS = MapUtil.get(params, "useCouponList", new cn.hutool.core.lang.TypeReference<List<Long>>() {
        });
        // 如果是null就转化为空集合
        if (CollUtil.isEmpty(useChooseCouponIDS)) {
            useChooseCouponIDS = new ArrayList<>();
        }
        MemberReceiveAddressEntityVo address = MapUtil.get(params, "address", MemberReceiveAddressEntityVo.class);
        if (address == null) {
            // 防止空下面空指针异常
            address = new MemberReceiveAddressEntityVo();
        }
        List<remarkVo> remark = MapUtil.get(params, "remark", new cn.hutool.core.lang.TypeReference<List<remarkVo>>() {
        });
        // 防止空指针异常
        if (CollUtil.isEmpty(remark)) {
            remark = new ArrayList<>();
        }
        // 根据 BUY_NOW 或者是 CART组装 cartList
        List<MemberCartEntityVo> memberCartEntityList = new ArrayList<>();
        // 两种形式 1:BUY_NOW 在详情页面点击立即购买进入结算界面 2:CART 购物车界面进入结算
        // 如果是BUY_NOW就要组装成新的cartVO在进行下一步计算
        if (type.equals("BUY_NOW")) {
            Long skuId = MapUtil.getLong(params, "skuId");
            String num = MapUtil.getStr(params, "num"); // 购买商品的数量
            SkuInfoEntity skuInfo = skuInfoService.getById(skuId);
            MemberCartEntityVo memberCartEntityVo = new MemberCartEntityVo();
            memberCartEntityVo.setSkuId(skuId);
            memberCartEntityVo.setMemberId(userId);
            memberCartEntityVo.setCatalogId(skuInfo.getCatalogId());
            memberCartEntityVo.setStoreId(skuInfo.getStoreId());
            memberCartEntityVo.setStoreName(skuInfo.getStoreName());
            memberCartEntityVo.setSkuPrice(skuInfo.getPrice());
            memberCartEntityVo.setProductCount(Long.parseLong(num));
            memberCartEntityList.add(memberCartEntityVo);
        }

        if (type.equals("CART")) {
            RespBean userCheckedCartEntityItemResp = memberFeignService.getUserCheckedCartEntityItem(userId);
            memberCartEntityList = JSON.parseObject(JSON.toJSONString(userCheckedCartEntityItemResp.getObj()), new TypeReference<List<MemberCartEntityVo>>() {
            });
        }

        /**
         * 前置判断库存 如果库存耗尽就直接返回
         */
        for (MemberCartEntityVo memberCartEntityVo : memberCartEntityList) {
            // 每个店铺里面的具体商品
            // 获取sku信息
            SkuInfoEntity sku = skuInfoService.getById(memberCartEntityVo.getSkuId());
            // 获取库存信息
            RespBean skuWareNumberResp = wareFeignService.getSkuWareNumber(sku.getSkuId());
            Integer skuStock = JSON.parseObject(JSON.toJSONString(skuWareNumberResp.getObj()), Integer.class);
            if (skuStock <= 0) {
                return RespBean.error(sku.getSkuName() + "的已售空");
            }
        }

        // 获取当前可用的优惠券
        RespBean userAllCanUseCouponByCARTResp = memberFeignService.getUserAllCanUseCouponByCART(memberCartEntityList);
        List<MemberCouponEntityVo> userAllCanUseCouponByCART = JSON.parseObject(JSON.toJSONString(userAllCanUseCouponByCARTResp.getObj()), new TypeReference<List<MemberCouponEntityVo>>() {
        });
        /**
         * 过滤出用户选择了的可用的优惠券
         */
        List<MemberCouponEntityVo> countCouponList = new ArrayList<>();
        for (MemberCouponEntityVo entity : userAllCanUseCouponByCART) {
            for (Long useChooseCouponID : useChooseCouponIDS) {
                if (useChooseCouponID.equals(entity.getCouponId())) {
                    countCouponList.add(entity);
                }
            }
        }
        // 计算价格
        PriceDetailDTO priceDetailDTO = new PriceDetailDTO();
        BigDecimal originalPrice = BigDecimal.ZERO;
        for (MemberCartEntityVo memberCartEntityVo : memberCartEntityList) {
            // 把购物车的物品的价格加起来
            originalPrice = originalPrice.add(memberCartEntityVo.getSkuPrice());
        }
        priceDetailDTO.setOriginalPrice(originalPrice); // 原始价格
        priceDetailDTO.setGoodsPrice(originalPrice);// 商品总金额（商品原价）
        BigDecimal freightPrice = BigDecimal.ZERO;
        priceDetailDTO.setFreightPrice(freightPrice); // 配送费 本功能还未做 先空着
        BigDecimal couponReducePrice = BigDecimal.ZERO;
        StringBuffer usePlatformMemberCouponIds = new StringBuffer(); //使用的平台会员优惠券id
        StringBuffer useStoreMemberCouponIds = new StringBuffer();
        for (MemberCouponEntityVo entity : countCouponList) {
            // 如果是满减类型
            if (entity.getCouponType().equals("PRICE")) {
                // 判断是优惠券是否满足使用门槛
                if (originalPrice.compareTo(entity.getConsumeThreshold()) == 1) {
                    couponReducePrice = couponReducePrice.add(entity.getPrice());
                    // 统计优惠券
                    if (entity.getStoreName().equals("platform")) {
                        usePlatformMemberCouponIds.append("," + entity.getCouponId());
                    } else {
                        useStoreMemberCouponIds.append("," + entity.getCouponId());
                    }
                }
            }
            // 如果优惠券是满减类型
            if (entity.getCouponType().equals("DISCOUNT")) {
                // 将最早的总价拿来然后计算折数
                if (originalPrice.compareTo(entity.getConsumeThreshold()) == 1) {
                    BigDecimal discount = entity.getDiscount().multiply(new BigDecimal("0.1"));
                    BigDecimal disCountNum = originalPrice.subtract(originalPrice.multiply(discount));
                    couponReducePrice = couponReducePrice.add(disCountNum);
                    // 统计优惠券
                    // 统计优惠券
                    if (entity.getStoreName().equals("platform")) {
                        usePlatformMemberCouponIds.append("," + entity.getCouponId());
                    } else {
                        useStoreMemberCouponIds.append("," + entity.getCouponId());
                    }
                }
            }
        }
        priceDetailDTO.setCouponPrice(couponReducePrice);// 优惠券减掉钱

        // 获取满减活动
        List<Long> skuIds = memberCartEntityList.stream().map(MemberCartEntityVo::getSkuId).collect(Collectors.toList());
        RespBean cartCheckFullDiscountResp = couponFeignService.getCartCheckFullDiscount(skuIds);
        List<FullDiscountEntityVo> fullDiscountList = JSON.parseObject(JSON.toJSONString(cartCheckFullDiscountResp.getObj()), new TypeReference<List<FullDiscountEntityVo>>() {
        });
        // 防止为空指针异常
        if (CollUtil.isEmpty(fullDiscountList)) {
            fullDiscountList = new ArrayList<>();
        }
        BigDecimal fullDiscountReducePrice = BigDecimal.ZERO;// 满减活动减掉的价格
        for (FullDiscountEntityVo fullDiscountEntityVo : fullDiscountList) {
            // 如果是减现金
            if (fullDiscountEntityVo.getFullMinusFlag()) {
                if (originalPrice.compareTo(fullDiscountEntityVo.getFullMoney()) == 1) {
                    fullDiscountReducePrice = fullDiscountReducePrice.add(fullDiscountEntityVo.getFullMinus());
                }
            } else {
                // 是满折
                if (originalPrice.compareTo(fullDiscountEntityVo.getFullMoney()) == 1) {
                    BigDecimal discount = fullDiscountEntityVo.getFullRate().multiply(new BigDecimal("0.1"));
                    BigDecimal disCountNum = originalPrice.subtract(originalPrice.multiply(discount));
                    fullDiscountReducePrice = fullDiscountReducePrice.add(disCountNum);
                }
            }
        }
        priceDetailDTO.setDiscountPrice(fullDiscountReducePrice); // 满减减掉的金额
        BigDecimal totalReduce = fullDiscountReducePrice.add(couponReducePrice); // 现在全部减掉的金额
        BigDecimal flowPrice = originalPrice.subtract(totalReduce).subtract(freightPrice); // 最终订单价格 总价-全部优惠(满减+优惠券)-运费
        priceDetailDTO.setFlowPrice(flowPrice);
        // 计算数量
        Long count = 0L;
        for (MemberCartEntityVo memberCartEntityVo : memberCartEntityList) {
            count += memberCartEntityVo.getProductCount();
        }
        priceDetailDTO.setTotalNum(count);
        /**
         * 把之前算出来的 优惠券减少的价格 和满减减少的价格 和商品数量相除 然后平均分一下再各自计算priceDetail方便后期退款时结账
         */
        BigDecimal everyItemCouponReduce = couponReducePrice.divide(new BigDecimal(count.toString()));
        BigDecimal everyItemFullDiscountReduce = fullDiscountReducePrice.divide(new BigDecimal(count.toString()));

        // 生成订单
        List<Long> storeIds = memberCartEntityList.stream().map(MemberCartEntityVo::getStoreId).distinct().collect(Collectors.toList());
        // 生成全局统一的交易sn
        String tradeSN = "T" + IdWorker.getTimeId();
        Map<Long, CreateOrderDto> createOrderIds = new HashMap<>();
        for (Long storeId : storeIds) {
            String orderSn = "O" + IdWorker.getTimeId();//统一的SN订单
            List<Long> skus = new ArrayList<>();
            for (MemberCartEntityVo memberCartEntityVo : memberCartEntityList) {
                if (memberCartEntityVo.getStoreId().equals(storeId)){
                    skus.add(memberCartEntityVo.getSkuId());
                }
            }
            CreateOrderDto createOrderDto = new CreateOrderDto();
            createOrderDto.setOrderSN(orderSn);
            createOrderDto.setSkuIds(skus);
            createOrderIds.put(storeId,createOrderDto);
        }
        // 发送MQ生成订单
        DefaultMQProducer producer = new DefaultMQProducer("create-order-group");
        producer.setNamesrvAddr("192.168.253.128:9876");
        try {
            producer.start();
            Message message = new Message();
            message.setTopic("CreateOrderTopic");
            Map<String, Object> createOrderMap = new HashMap<>();
            createOrderMap.put("tradeSN", tradeSN);
            createOrderMap.put("address", address);
            createOrderMap.put("userId", userId);
            createOrderMap.put("userName", userName);
            createOrderMap.put("remark", remark);
            createOrderMap.put("createOrderIds", createOrderIds);
            createOrderMap.put("memberCartEntityList", memberCartEntityList);
            createOrderMap.put("everyItemFullDiscountReduce", everyItemFullDiscountReduce);
            createOrderMap.put("everyItemCouponReduce", everyItemCouponReduce);
            createOrderMap.put("usePlatformMemberCouponIds", usePlatformMemberCouponIds.toString());
            createOrderMap.put("useStoreMemberCouponIds", useStoreMemberCouponIds.toString());
            createOrderMap.put("priceDetailDTO", priceDetailDTO);
            message.setBody(JSON.toJSONString(createOrderMap).getBytes(StandardCharsets.UTF_8));
            SendResult send = producer.send(message);
            log.info("创建订单消息发送结果:{}", send.getSendStatus());
        } catch (MQClientException | RemotingException | MQBrokerException | InterruptedException e) {
            e.printStackTrace();
            return RespBean.error("创建订单失败:" + e.getMessage());
        } finally {
            try {
                producer.shutdown();
                System.out.println("创建订单链接已关闭");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        // 发送MQ生成锁库存的工单
        DefaultMQProducer createTask = new DefaultMQProducer("create-ware-task");
        createTask.setNamesrvAddr("192.168.253.128:9876");
        try {
            createTask.start();
            Message message = new Message();
            message.setTopic("CreateWareTask");
            Map<String, Object> createTaskMap = new HashMap<>();
            createTaskMap.put("createOrderIds", createOrderIds);
            createTaskMap.put("address", address);
            createTaskMap.put("memberCartEntityList", memberCartEntityList);
            message.setBody(JSON.toJSONString(createTaskMap).getBytes(StandardCharsets.UTF_8));
            SendResult sendCreateTask = createTask.send(message);
            log.info("创建工单消息已发送，结果:{}", sendCreateTask.getSendStatus());
        } catch (MQClientException | RemotingException | MQBrokerException | InterruptedException e) {
            e.printStackTrace();
            return RespBean.error("创建锁库存工单失败:" + e.getMessage());
        } finally {
            try {
                createTask.shutdown();
                System.out.println("创建工单链接已关闭");
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
        return RespBean.success("完成", tradeSN);
    }

    /**
     * 交易详情
     *
     * @param params
     * @return
     */
    @Override
    public RespBean tradeDetail(Map<String, Object> params) {

        return RespBean.success("1");
    }


}
